ホームに戻る
出典 :
方法: バインド検証を実装する - WPF | Microsoft Learn ValidationRule クラス (System.Windows.Controls) | Microsoft Learn ValidationStep 列挙型 (System.Windows.Controls) | Microsoft Learn NotifyDataErrorValidationRule クラス (System.Windows.Controls) | Microsoft Learn Binding.ValidatesOnNotifyDataErrors プロパティ (System.Windows.Data) | Microsoft Learn 【C#/WPF】MVVMパターンで実装するTextBoxバリデーション手法の完全解説 | hn_pgtech
関連 :
データバインディング バインディングに関わるプロパティ MVVMパターン スタイル ControlTemplate
目次 :

バリデーション(検証)

ユーザが入力した値の有効・無効を判定するとともに、無効な値が入力された旨をユーザに視覚的に通知することができる。

バリデーションの類型

バリデーションを View で行うか、ViewModel / Model で行うかによって実装が異なる。

View でのバリデーション

Binding (単一プロパティ)単位

単一のプロパティに対してのチェックを行う。
検証ルールの定義 : RangeRule.cs
画像
View : ####.xaml (抜粋)
画像
解説
TextBox の入力値を検証する場合の例。検証ルールは ValidationRule を継承して作成する。 値の判定は Validate() メソッドで行う。Validate() はソース(ここでは Age プロパティ)の値が変化したタイミングでコールされる。 (UpateSourceTrigger="PropertyChanged" により、値は入力後即座に反映される。入力された値は第1引数 value に格納される。) 戻り値 ValidationResult 型のコンストラクタは第1引数に value の有効( true )・無効( false )、第2引数にエラーの内容をとる。 ValidationResult.ValidResult は ValidationResult(true, null) と等価。 View 内で完結し、実装も比較的単純だが、ViewModel を介さないためテストが難しいという欠点もある。

BindingGroup (複数プロパティ)単位

複数プロパティの相関チェックを行う。「保存時にまとめて検証を行う」場合に有効。
検証ルールの定義 : DateRangeRule.cs
画像
View : ####.xaml (抜粋)
画像
解説
BindingGroup (詳細はリンク先参照)を検証する場合の例。 ValidationRule の適用時に ValidationStep を指定し、検証( Validate() )が行われるタイミングを制御(ここではコミット時)する。

ViewModel / Model でのバリデーション

INotifyDataErrorInfo

現在のWPFで主流となっている手法。MVVMモデルと相性がよく、非同期のチェックにも対応している。
ViewModel : PersonViewModel.cs
画像
View : ####.xaml (抜粋)
画像
解説
ViewModel または Model に INotifyDataErrorInfo を実装し、データバインディング時に ValidatesOnNotifyDataErrors を true に設定することで、 当該 ViewModel / Model に組み込まれた NotifyDataErrorValidationRule を ValidationRules に関連付けることができる。 ErrorsChanged イベント、HasErrors プロパティ、GetErrors() メソッドは、INotifyDataErrorInfo によって定義される。 ここでは PersonViewModel.Name の値が更新された際に検証を行い、不正な値であればエラー一覧にプロパティ名とエラーの内容のペアを追加するとともに、 ErrorsChanged イベントを発行し、エラー状態の変化を通知する。 すべての処理が ViewModel / Model で完結するためテストが容易である。 なお、以前は IDataErrorInfo が用いられていたが、より改良された INotifyDataErrorInfo によって置き換えられ、現在は推奨されていない。

エラーの表示 (Validation.ErrorTemplate)

View : ####.xaml (抜粋)
画像
解説
ここでは、ErrorTemplate をスタイルとして定義している。TextBox の入力値が有効でない場合、エラー内容を赤字で表示する。 ControlTemplate を編集することで、表示方法をカスタマイズできる。 AdornedElementPlaceholder はバリデーションの対象となるコントロール(ここでは TextBox )の位置を表すプレースホルダである。 エラー内容を取得する際に Binding.ElementName を用いるため、AdornedElementPlaceholder.Name をそのまま用いる。

実装例 : TextBox

画像 有効な値は 0 以上 10 未満の数値で、それ以外が入力されると TextBox の枠を赤色とし、エラーの内容を TextBox の下に表示する。
View : MainWindow.xaml
画像
ValidationRule : TextBoxRule.cs
画像
ViewModel 基底クラス : ViewModelBase.cs
画像
ViewModel : SampleViewModel.cs
画像
解説
ここでは ValidationRule と INotifyDataErrorInfo それぞれを用いたバリデーションを行っている。検証内容は共通である。 ErrorTemplate は共通で、Window のリソースとして定義している。 INotifyDataErrorInfo は ViewModel に直接記述するのではなく、INotifyDataErrorInfo を実装した基底クラス( ViewModelBase )を作成している。 これによりボイラープレートの縮小を目論んでいる。 ValidateProperty() は抽象メソッドであるため、具象クラスでオーバーライドが必要である。 引数にとったプロパティ名に応じて処理を分化できるため、複数のプロパティを取り扱うことが可能である。